package com.xiantm.study.thread.future.p3.impl;

import com.xiantm.study.thread.future.p3.Content;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class AsyncContentImpl implements Content {


    private final FutureTask<byte[]> content;

    public AsyncContentImpl(final String urlstr){
        content = new FutureTask(() -> {
            byte[] contentBytes;
            System.out.println(Thread.currentThread().getName() + ": Getting " + urlstr);
            try {
                URL url = new URL(urlstr);
                DataInputStream in = new DataInputStream(url.openStream());
                byte[] buffer = new byte[1];
                int index = 0;
                try {
                    while (true){
                        int c = in.readUnsignedByte();
                        if (buffer.length<= index){
                            byte[] largeBuffer = new byte[buffer.length * 2];
                            System.arraycopy(buffer,0,largeBuffer,0 ,index);
                            buffer = largeBuffer;
                        }
                        buffer[index++] = (byte) c;
                    }
                }catch (EOFException e){
                    e.printStackTrace();
                }finally {
                    in.close();
                }
                contentBytes = new byte[index];
                System.arraycopy(buffer, 0, contentBytes, 0, index);
                return contentBytes;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return new byte[0];
        });
        new Thread(content).start();
    }


    @Override
    public byte[] getBytes(){
        try {
            return content.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return new byte[0];
        }
    }
}
